
package com.be.beadmin.project.impl;


import com.be.beadmin.basicData.entity.User;
import com.be.beadmin.basicData.repository.UserRepository;
import com.be.beadmin.basicData.service.UserService;
import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaSortBuilder;
import com.be.beadmin.project.dto.input.TeamDto;
import com.be.beadmin.project.dto.input.TeamInfoDto;
import com.be.beadmin.project.dto.output.*;
import com.be.beadmin.project.entity.*;
import com.be.beadmin.project.mapper.TeamInfoMapper;
import com.be.beadmin.project.mapper.TeamInfoMapperEx;
import com.be.beadmin.project.mapper.TeamMapper;
import com.be.beadmin.project.mapper.TeamMapperEx;
import com.be.beadmin.project.repository.InfoRepository;
import com.be.beadmin.project.repository.TeamInfoRepository;
import com.be.beadmin.project.repository.TeamRepository;
import com.be.beadmin.project.service.InfoService;
import com.be.beadmin.project.service.TeamInfoService;
import com.be.beadmin.project.service.TeamService;
import com.be.beadmin.service.dto.output.DictDataEx;
import com.be.beadmin.service.entity.DictType;
import com.be.beadmin.service.repository.DictTypeRepository;
import com.be.beadmin.service.service.DictDataService;
import com.be.beadmin.service.service.DictTypeService;
import com.be.beadmin.service.service.SerialNumberService;
import lombok.RequiredArgsConstructor;
import org.junit.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;

/**
* @description 服务实现
* @author zjm
* @date 2023-02-02
**/
@Service
@RequiredArgsConstructor
public class TeamServiceImpl implements TeamService {

    @Autowired
    private TeamRepository teamRepository;
    @Autowired
    private  InfoRepository infoRepository;
    @Autowired
    private InfoService infoService;
    @Autowired
    private UserService userService;
    @Autowired
    private DictTypeService dictTypeService;
    @Autowired
    private TeamInfoService teamInfoService;
    @Autowired
    private TeamInfoMapper teamInfoMapper;
    @Autowired
    private TeamInfoMapperEx teamInfoMapperEx;
    @Autowired
    private DictTypeRepository  dictTypeRepository;
    @Autowired
    private DictDataService dictDataService;
    @Autowired
    private TeamMapper teamMapper;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private SerialNumberService serialNumberService;
//    @Autowired
//    private DictDataService dictDataService;

    @Autowired
    private TeamMapperEx teamExMapper;
    @Autowired
    private TeamInfoRepository teamInfoRepository;

    @Override
    public Page<TeamEx> getTeamByPage(PageEntity pageEntity) {
            Pageable pageable = PageRequest.of(
            pageEntity.getCurrent() -1,
            pageEntity.getPageSize());
            Page<Team> page = teamRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 =   JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(Team_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if(pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(Team_.createTime).as(Date.class)));
                    }
                    return  criteriaBuilder.and(list.toArray(p));
                    }
                    , pageable);
            Page<TeamEx> page1 = page.map(teamExMapper::toEntity);
            return page1;

    }

//    @Override
//    public Object getTeamRefInfo(PageEntity projectPageEntity,PageEntity userPageEntity,PageEntity userTypePageEntity) {
//        // 1. 所有项目信息
//        Page<InfoEx> infoByPage = infoService.getInfoByPage(projectPageEntity);
////        System.out.println("infoByPage:"+infoByPage);
////        infoService.getInfoByPage();
//
//        // 2. 所有用户信息
//        Page<UserEx> userByPage = userService.getUserByPage(projectPageEntity);
//
//        // 3. 角色类型字典内容
//        DictTypeEx dictTypeEx = dictTypeService.getDictTypeByName("项目团队角色类型");
//        String userTypeCode = dictTypeEx.getDictCode();
////        PageEntity DDpageEntity = new PageEntity();
////        DDpageEntity.setCurrent(1);
////        DDpageEntity.setPageSize(10);
//        List<DictDataEx> userTypeByPage =  dictDataService.getDictDataByDictTypeId(userTypeCode);
////        PageEntity DTpageEntity = new PageEntity();
////        DTpageEntity.setCurrent(1);
////        DTpageEntity.setPageSize(10);
////        Page<DictTypeEx> dictTypeByPage = dictTypeService.getDictTypeByPage(DTpageEntity);
////        List<DictTypeEx> dictTypeExList = dictTypeByPage.getContent();
////        dictTypeExList.
//
//        HashMap<String,Page> response = new HashMap<>();
//        response.put("project",infoByPage);
//        response.put("user",userByPage);
//        response.put("userType",userTypeByPage);
//
//
//        return response;
//    }

    @Override
    public List<String> getRoleType() {

        // 角色类型字典内容
//        DictTypeEx dictTypeEx = dictTypeService.getDictTypeByName("项目团队角色类型");
        DictType dictType = dictTypeRepository.findDictTypeByDictName("项目团队角色类型");
//        System.out.println("dictTypeEx:"+dictTypeEx);
//        String roleTypeCode = dictTypeEx.getDictCode();
//        System.out.println("roleTypeCode:"+roleTypeCode);
        List<DictDataEx> roleType =  dictDataService.getDictDataExByDictTypeId(dictType);
        List<String> roleTypeList = new ArrayList<>();
        roleType.forEach(role-> roleTypeList.add(role.getKeyName()));
        return roleTypeList;
    }

    /**
     * 获取所有的项目的简易信息
     *
     * @return
     */
    @Override
    public List<ProjectInfoSimpEx> getProjectInfoSimp() {
        List<Info> infoList = infoRepository.findAll();
        List<ProjectInfoSimpEx> projectInfoSimps = new ArrayList<>();
        for (int i = 0; i < infoList.size(); i++) {
            ProjectInfoSimpEx projectInfoSimp = new ProjectInfoSimpEx();
            projectInfoSimp.setInfoId(infoList.get(i).getId());
            projectInfoSimp.setProjectName(infoList.get(i).getProjectName());
//            projectInfoSimp.setInfoId(infoList.get(i).getProjectCode());
            if (infoList.get(i).getDelete()==0){
                projectInfoSimps.add(projectInfoSimp);
            }

        }

        return projectInfoSimps;
    }

    /**
     * 获取指定id的团队信息
     *
     * @param teamId
     * @return
     */
    @Override
    public Team getTeamByIdAndDelete(String teamId) {

        return teamRepository.findTeamByIdAndDelete(teamId,0);

    }

    @Override
    public Page<Object> getTeamAndProjectByPage(PageEntity pageEntity) {
        Page<Info> infoPage = infoService.getInfoByPageOrigin(pageEntity);
        Page<Object> page =  infoPage.map(new Function<Info, Object>() {
            @Override
            public Object apply(Info info) {
                if (info.getTeamId() == null) return null;
                Team team = teamRepository.findTeamByIdAndDelete(info.getTeamId(),0);
                TeamAndProjectEx teamAndProjectEx = new TeamAndProjectEx();
                teamAndProjectEx.setInfoId(info.getId());
                teamAndProjectEx.setProjectName(info.getProjectName());
                teamAndProjectEx.setTeamId(team.getId());
                teamAndProjectEx.setTeamName(team.getTeamName());
                teamAndProjectEx.setTeamCode(team.getTeamCode());
                return teamAndProjectEx;
            }
        });

        return page;
    }

    /**
     * 根据项目ID获取该项目团队信息
     *
     * @param infoId
     * @return
     */
    @Override
    public ProjectTeamEx getProjectTeamInfos(String infoId) {
        Info info = infoRepository.findInfoByIdAndDelete(infoId,0);
        if (info == null) throw new BeadminException("没找到该项目[infoId:"+infoId+"]");
        if (info.getTeamId() == null) { // 没有找到团队 直接给他设置默认团队
            setInfoDefaultTeam(info);
            infoRepository.save(info);
        }
        Team team = teamRepository.findTeamByIdAndDelete(info.getTeamId(),0);
        if (team == null) throw new BeadminException("没找到该团队[teamId:"+info.getTeamId()+"]没有团队");
        ProjectTeamEx projectTeamEx = new ProjectTeamEx(); // 新建
        projectTeamEx.setTeamId(team.getId());
        projectTeamEx.setTeamName(team.getTeamName());
        projectTeamEx.setTeamCode(team.getTeamCode());
//        List<TeamInfoEx> teamInfoExes = new ArrayList<>();
        List<TeamInfo> teamInfos = teamInfoRepository.findTeamInfosByTeamIdAndDelete(team.getId(),0);
        List<TeamInfoEx> teamInfoExes = teamInfoMapperEx.toEntity(teamInfos);
//        teamInfoExes.forEach(new Consumer<TeamInfoEx>() {
//            @Override
//            public void accept(TeamInfoEx teamInfoEx) {
//                User userById = userService.getUserById(teamInfoEx.getUserId());
//                if (null!=userById) {
//                    teamInfoEx.setPhone(userById.getPhone());
//                    teamInfoEx.setEmail(userById.getEmail());
//                }
//            }
//        });
        projectTeamEx.setTeamInfos(teamInfoExes);

        return projectTeamEx;
    }

    /**
     * 根据项目ID和团队ID更换项目团队
     *
     * @param infoId
     * @param teamId
     * @return
     */
    @Override
    public String changeProjectTeam(String infoId, String teamId) {
        Info info = infoRepository.findInfoByIdAndDelete(infoId,0);
        if (info == null) throw new BeadminException("没找到该项目[infoId:"+infoId+"]");
        info.setTeamId(teamId);
        infoRepository.save(info);
        return "更换成功";
    }

    @Override
    public List<ProjectTeamEx> getTeamInfos() {
        List<ProjectTeamEx> projectTeamExes = new ArrayList<>();
        List<Team> teams =  teamRepository.findAllByStateAndDelete(1,0);
        for (Team t :
                teams) {
            ProjectTeamEx projectTeamEx = new ProjectTeamEx();
            projectTeamEx.setTeamId(t.getId());
            projectTeamEx.setTeamName(t.getTeamName());
            projectTeamEx.setTeamCode(t.getTeamCode());
            List<TeamInfo> teamInfos = teamInfoRepository.findTeamInfosByTeamIdAndDelete(t.getId(), 0);
            List<TeamInfoEx> teamInfoExes = teamInfoMapperEx.toEntity(teamInfos);
            projectTeamEx.setTeamInfos(teamInfoExes);
            projectTeamExes.add(projectTeamEx);
        }
        return projectTeamExes;
    }

    @Override
    public void setInfoDefaultTeam(Info info) {
        List<Team> list = teamRepository.findTeamByTeamNameAndDelete("默认团队", 0);
        if (list.size() == 0) throw new BeadminException("没有默认团队，请先添加一个默认团队");
        info.setTeamId(list.get(0).getId()); //默认团队

    }

    /**
     * 更新团队的状态：是否有效
     * @param teamId
     */
    @Override
    public void updateTeamState(String teamId) {

        Team team = teamRepository.findTeamByIdAndDelete(teamId, 0);

        // 查询团队中是否存在这些角色
        List<String> list = dictDataService.getDictDataKeyByDictTypeName("有效团队角色");
        if (list == null) {
            throw new BeadminException("未找到有效团队角色字典");

        }
        /**
         * 有效团队需要满足以下条件：
         * 条件1：团队中包含所有必填角色
         * 条件2：团队中只能包含一名项目经理、生产经理、技术经理
         */
        // 条件1：团队中包含所有必填角色
        List<String> list1 = teamInfoRepository.validTeamRole(team.getId());
        if (list1.size() == 0 ) { // 说明所有需要的角色都包含
            // 条件2：团队中只能包含一名项目经理、生产经理、技术经理
            List<Integer> onlyOneManager = teamInfoRepository.isOnlyOneManager(team.getId());
            if (onlyOneManager.size() == 0 ) { // 没有超过一个的
                team.setState(1); // 有效
            } else {
                team.setState(0); // 无效
            }
        } else {

            team.setState(0); // 无效
        }
        teamRepository.save(team);
    }


    /**
     * {
     *   "team": {
     *     "contractCode": "CC00000646",
     *     "id": "5",
     *     "memo": "",
     *     "projectName": "项目3",
     *     "reserved": "",
     *     "serialNo": "PT001",
     *     "teamCode": "TC001",
     *     "teamName": "项目三的团队"
     *   },
     *   "teamInfoList": [
     *     {
     *       "category": "项目经理",
     *       "id": "1",
     *       "memo": "",
     *       "reserved": "",
     *       "roleId": "402881ed854de8d201854de9143a000d",
     *       "roleName": "项目经理",
     *       "serialNo": "TI001",
     *       "teamId": "5",
     *       "userId": "402881ed854de8d201854de911030000",
     *       "userName": "admin"
     *     },
     *     {
     *       "category": "采购",
     *       "id": "2",
     *       "memo": "",
     *       "reserved": "",
     *       "roleId": "402881ed854de8d201854de911f10003",
     *       "roleName": "采购经理",
     *       "serialNo": "TI002",
     *       "teamId": "5",
     *       "userId": "402881ed854de8d201854de911030000",
     *       "userName": "admin"
     *     }
     *   ]
     * }
     */
    /**
     *
     * @param teamEntity
     */
    @Override
    public void addTeam(TeamEntity teamEntity) {
//            TeamDto teamDto = teamEntity.getTeam();
//            List<TeamInfoDto> teamInfoDtos = teamEntity.getTeamInfoList();
//            // 存入团队
//            Team result = teamRepository.findTeamByTeamNameAndInfoIdAndDelete(teamDto.getTeamName(),teamDto.getInfoId(), 0);
////            if(ObjectUtil.isNotEmpty(result)) {
////                throw new BeadminException("Team不存在,请重新查询");
////            }
//            System.out.println("Teamresult:"+result);
//
//            Team team = teamMapper.toEntity(teamDto);
//            Team saveteam = teamRepository.save(team);
//
//            //存入团队信息
//            teamInfoService.addTeamInfos(teamInfoDtos,saveteam);
//            return 1;
    }

    @Transactional
    @Override
    public int addTeam(TeamDto teamDto) {
//        System.out.println("teamDto-service:"+teamDto);
//        Team result = teamRepository.findTeamByIdAndDelete(teamDto.getId(), 0);

//        if(ObjectUtil.isNotEmpty(result)) {
//            throw new BeadminException("Team已存在,请勿重复添加！！");
//        }
        List<Team> result = teamRepository.findTeamByTeamNameAndDelete(teamDto.getTeamName(), 0);

        if(result.size()!=0) {
            return -1;
        }
        Team team = teamMapper.toEntity(teamDto);
        team.setTeamCode(serialNumberService.getNextSnByCode("TeamInfoCode"));
//        Info info = infoRepository.findInfoById(teamDto.getInfoId());
//        team.set(info);
//        System.out.println("team:"+team.toString());
        Team teamSave = teamRepository.save(team);
//        List<String> typeNames = dictDataService.getDictDataKeyByDictTypeName("项目团队角色类型");
//        List<TeamInfoDto> teamInfoDtos = new ArrayList<>();
//        for (String t :
//                typeNames) {
//            User user = userRepository.findUserByNameAndDelete("张三",0);
//            TeamInfoDto teamInfoDto = new TeamInfoDto();
//            teamInfoDto.setTeamId(teamSave.getId());
//            teamInfoDto.setCategory(t);
//            teamInfoDto.setUserId(user.getId());
//            teamInfoDto.setUserName(user.getName());
//            teamInfoDtos.add(teamInfoDto);
//        }
//        teamInfoRepository.saveAll(teamInfoMapper.toEntity(teamInfoDtos));

        return 1;
    }

    @Override
    public int updateTeam(TeamDto teamDto) {
//        List<Team> result = teamRepository.findTeamByTeamNameAndInfoIdAndDelete(teamDto.getTeamName(),teamDto.getInfoId(), 0);
//        if(result.size()!=0) {
//            return -1;
//        }
        Team result = teamRepository.findTeamByIdAndDelete(teamDto.getId(),0);
//        if() {
//            return -1;
//        }
        Team team = teamMapper.toEntity(teamDto);
        teamRepository.save(team);
        return 1;
    }


    @Override
    public void delTeam(String id) {
        Team team = teamRepository.findTeamById(id);
        teamInfoRepository.deleteTeamInfoByInfoIdAndDelete(1, team.getId(), 0);
        team.setDelete(1);
        teamRepository.save(team);
    }

    @Override
    public void delTeams (List<String> ids) { }
}